package com.cbgolf.oa.app;

import android.content.Context;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
import android.text.TextUtils;
import android.util.Log;
import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.cbgolf.oa.util.DataUtil;
import com.cbgolf.oa.widget.autolayout.config.AutoLayoutConifg;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.utils.StorageUtils;
import com.tencent.bugly.crashreport.CrashReport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.xutils.DbManager;
import org.xutils.db.table.TableEntity;
import org.xutils.x;


/**
 * @author Created by lq on 2017/8/24.
 */

public class App extends MultiDexApplication {

  private static Context context;
  private static DbManager.DaoConfig daoConfig;


  public static boolean isUpDataCheckPermission;
  public static boolean isUpDataCanceled;
  public static boolean isUpdataShowDownLoad;

  public static DbManager.DaoConfig getDaoConfig() {
    return daoConfig;
  }

//  private RefWatcher refWatcher;
//
//  public static RefWatcher getRefWatcher(Context context) {
//    App application = (App) context.getApplicationContext();
//    return application.refWatcher;
//  }

  @Override
  protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
  }

  public static Context getContext() {
    return context;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    init();
  }

  private void init() {
    context = getApplicationContext();
    initX();
    initAutoLayout();
    initImageLoader();
    initBugly();
//    initEasyHttp();
//    initLeakCanary();
    initCloudChannel(this);
//    initAppStatusListener();
  }

//  private void initLeakCanary() {
//    if (LeakCanary.isInAnalyzerProcess(this)) {
//      // This process is dedicated to LeakCanary for heap analysis.
//      // You should not init your app in this process.
//      return;
//    }
//    refWatcher = LeakCanary.install(this);
////    LeakCanary.install(this);
//  }

//  private void initAppStatusListener() {
//    ForegroundCallbacks.init(this).addListener(new ForegroundCallbacks.Listener() {
//      @Override
//      public void onBecameForeground() {
//        Log.e("WsManager------------", "应用回到前台调用重连方法");
//        WsManager.getInstance().reconnect();
//      }
//
//      @Override
//      public void onBecameBackground() {
//
//      }
//    });
//  }

//  private void initEasyHttp() {
//    /**
//     * 默认初始化,必须调用
//     */
//    EasyHttp.init(this);
//    //全局设置请求头
//    HttpHeaders headers = new HttpHeaders();
//    headers.put("X-Auth-Token", DataUtil.getToken());
//    //全局设置请求参数
//    HttpParams params = new HttpParams();
////    params.put("appId", AppConstant.APPID);
//    //以下设置的所有参数是全局参数,同样的参数可以在请求的时候再设置一遍,那么对于该请求来讲,请求中的参数会覆盖全局参数
//    EasyHttp.getInstance()
//        //可以全局统一设置全局URL
//        .setBaseUrl(WebAPI.BASEURL)//设置全局URL  url只能是域名 或者域名+端口号
//        // 打开该调试开关并设置TAG,不需要就不要加入该行
//        // 最后的true表示是否打印内部异常，一般打开方便调试错误
//        .debug("EasyHttp", true)
//
//        //如果使用默认的60秒,以下三行也不需要设置
//        .setReadTimeOut(60 * 1000)
//        .setWriteTimeOut(60 * 100)
//        .setConnectTimeout(60 * 100)
//
//        //可以全局统一设置超时重连次数,默认为3次,那么最差的情况会请求4次(一次原始请求,三次重连请求),
//        //不需要可以设置为0
//        .setRetryCount(3)//网络不好自动重试3次
//        //可以全局统一设置超时重试间隔时间,默认为500ms,不需要可以设置为0
//        .setRetryDelay(500)//每次延时500ms重试
//        //可以全局统一设置超时重试间隔叠加时间,默认为0ms不叠加
//        .setRetryIncreaseDelay(500)//每次延时叠加500ms
//
//        //可以全局统一设置缓存模式,默认是不使用缓存,可以不传,具体请看CacheMode
//        .setCacheMode(CacheMode.NO_CACHE)
//        //可以全局统一设置缓存时间,默认永不过期
//        .setCacheTime(-1)//-1表示永久缓存,单位:秒 ，Okhttp和自定义RxCache缓存都起作用
//        //全局设置自定义缓存保存转换器，主要针对自定义RxCache缓存
//        .setCacheDiskConverter(new SerializableDiskConverter())//默认缓存使用序列化转化
//        //全局设置自定义缓存大小，默认50M
//        .setCacheMaxSize(100 * 1024 * 1024)//设置缓存大小为100M
//        //设置缓存版本，如果缓存有变化，修改版本后，缓存就不会被加载。特别是用于版本重大升级时缓存不能使用的情况
//        .setCacheVersion(1)//缓存版本为1
//        //.setHttpCache(new Cache())//设置Okhttp缓存，在缓存模式为DEFAULT才起作用
//
//        //可以设置https的证书,以下几种方案根据需要自己设置
//        .setCertificates()                                  //方法一：信任所有证书,不安全有风险
//        //.setCertificates(new SafeTrustManager())            //方法二：自定义信任规则，校验服务端证书
//        //配置https的域名匹配规则，不需要就不要加入，使用不当会导致https握手失败
//        //.setHostnameVerifier(new SafeHostnameVerifier())
//        //.addConverterFactory(GsonConverterFactory.create(gson))//本框架没有采用Retrofit的Gson转化，所以不用配置
//        .addCommonHeaders(headers)//设置全局公共头
//        .addCommonParams(params);//设置全局公共参数
//        //.addNetworkInterceptor(new NoCacheInterceptor())//设置网络拦截器
//        //.setCallFactory()//局设置Retrofit对象Factory
//        //.setCookieStore()//设置cookie
//        //.setOkproxy()//设置全局代理
//        //.setOkconnectionPool()//设置请求连接池
//        //.setCallbackExecutor()//全局设置Retrofit callbackExecutor
//        //可以添加全局拦截器，不需要就不要加入，错误写法直接导致任何回调不执行
//        //.addInterceptor(new GzipRequestInterceptor())//开启post数据进行gzip后发送给服务器
////        .addInterceptor(new CustomSignInterceptor());//添加参数签名拦截器
//  }

  private void initBugly() {
//        CrashReport.initCrashReport(getApplicationContext(), "ff5ad82e96", false);
    // 获取当前包名
    String packageName = context.getPackageName();
// 获取当前进程名
    String processName = getProcessName(android.os.Process.myPid());
// 设置是否为上报进程
    CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
    strategy.setUploadProcess(processName == null || processName.equals(packageName));
// 初始化Bugly
    strategy.setAppReportDelay(20000);   //改为20s
    strategy.setCrashHandleCallback(new CrashReport.CrashHandleCallback() {
      @Override
      public synchronized Map<String, String> onCrashHandleStart(int i, String s, String s1,
          String s2) {
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        map.put("id--", DataUtil.getUserPhone());
        map.put("Tk--", DataUtil.getToken());
        return map;
      }

      @Override
      public synchronized byte[] onCrashHandleStart2GetExtraDatas(int i, String s, String s1,
          String s2) {
        return super.onCrashHandleStart2GetExtraDatas(i, s, s1, s2);
      }
    });
    CrashReport.initCrashReport(context, "ff5ad82e96", false, strategy);
//        CrashReport.setUserId(DataUtil.getUserPhone());

// 如果通过“AndroidManifest.xml”来配置APP信息，初始化方法如下
// CrashReport.initCrashReport(context, strategy);
  }

  /**
   * 获取进程号对应的进程名
   *
   * @param pid 进程号
   * @return 进程名
   */
  private static String getProcessName(int pid) {
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
      String processName = reader.readLine();
      if (!TextUtils.isEmpty(processName)) {
        processName = processName.trim();
      }
      return processName;
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    } finally {
      try {
        if (reader != null) {
          reader.close();
        }
      } catch (IOException exception) {
        exception.printStackTrace();
      }
    }
    return null;
  }

  private void initAutoLayout() {
    AutoLayoutConifg.getInstance().useDeviceSize();
  }

  private void initX() {
    x.Ext.init(this);
    daoConfig = new DbManager.DaoConfig()
        .setDbName("MANNGER")//创建数据库的名称
        .setDbVersion(1)//数据库版本号
        .setTableCreateListener(new DbManager.TableCreateListener() {
          @Override
          public void onTableCreate(DbManager dbManager, TableEntity<?> tableEntity) {
            Log.e("userdata-table:", "create--");
            //开启数据库支持多线程操作，提升性能
//                        dbManager.getDatabase().enableWriteAheadLogging();
          }
        })
        .setAllowTransaction(true)
        .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
          @Override
          public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
            // TODO: ...
            // db.addColumn(...);

            // db.dropTable(...);
            // ...
          }
        });//数据库更新操作

  }

  private void initImageLoader() {
    try {
      File cacheDir = StorageUtils.getCacheDirectory(context);  //缓存文件夹路径
      int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取当前应用程序所分配的最大内存
      int cacheSize = maxMemory / 8;//只分5分之一用来做图片缓存
      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
          .threadPoolSize(3) // default  线程池内加载的数量
          .denyCacheImageMultipleSizesInMemory()
//                    .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现
          .memoryCache(new LruMemoryCache(cacheSize)) //可以通过自己的内存缓存实现
//                    .memoryCacheSize(2 * 1024 * 1024)  // 内存缓存的最大值
          .memoryCacheSize(cacheSize)  // 内存缓存的最大值
//                .diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定义缓存路径
          .diskCache(new UnlimitedDiskCache(cacheDir))// 自定义缓存路径
          .diskCacheSize(100 * 1024 * 1024) // 100 Mb sd卡(本地)缓存的最大值
          // default为使用HASHCODE对UIL进行加密命名， 还可以用MD5(new Md5FileNameGenerator())加密
          .diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
          .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
          .build(); //开始构建
      ImageLoader.getInstance().init(config);
    } catch (Exception e) {
      Log.e("imageLoader_catch:", e.toString() + "");
    }
  }

  public static CloudPushService pushService;
  public static boolean pushBindSuccess;

  /**
   * 初始化云推送通道
   */
  private void initCloudChannel(Context applicationContext) {
    PushServiceFactory.init(applicationContext);
    pushService = PushServiceFactory.getCloudPushService();
    pushService.register(applicationContext, new CommonCallback() {
      @Override
      public void onSuccess(String s) {
        pushBindSuccess = true;
      }

      @Override
      public void onFailed(String s, String s1) {
      }
    });
  }
}


